home *** CD-ROM | disk | FTP | other *** search
- #ifndef __STD_RW_LOCIMPL__
- #define __STD_RW_LOCIMPL__
- #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
-
- /***************************************************************************
- *
- * rw/locimpl - Declarations for the Standard Library locale private
- * implementation classes.
- *
- * $Id: locimpl,v 1.26 1996/10/22 05:12:47 delaney Exp $
- *
- ***************************************************************************
- *
- * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
- * ALL RIGHTS RESERVED *
- * The software and information contained herein are proprietary to, and
- * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
- * intends to preserve as trade secrets such software and information.
- * This software is furnished pursuant to a written license agreement and
- * may be used, copied, transmitted, and stored only in accordance with
- * the terms of such license and with the inclusion of the above copyright
- * notice. This software and information or any other copies thereof may
- * not be provided or otherwise made available to any other person.
- *
- * Notwithstanding any other lease or license that may pertain to, or
- * accompany the delivery of, this computer software and information, the
- * rights of the Government regarding its use, reproduction and disclosure
- * are as set forth in Section 52.227-19 of the FARS Computer
- * Software-Restricted Rights clause.
- *
- * Use, duplication, or disclosure by the Government is subject to
- * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
- * Technical Data and Computer Software clause at DFARS 252.227-7013.
- * Contractor/Manufacturer is Rogue Wave Software, Inc.,
- * P.O. Box 2328, Corvallis, Oregon 97339.
- *
- * This computer software and information is distributed with "restricted
- * rights." Use, duplication or disclosure is subject to restrictions as
- * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
- * Computer Software-Restricted Rights (April 1985)." If the Clause at
- * 18-52.227-74 "Rights in Data General" is specified in the contract,
- * then the "Alternate III" clause applies.
- *
- **************************************************************************/
-
-
- #include <stdcomp.h>
-
- // Macros for declaring and referencing implementation type and object names in
- // our private implementation namespace, or with our private prefix __rw_ stuck
- // on the fronts of the names if namespaces are not supported by the compiler.
- // The DECL version is for use inside the implementation namespace, the NAME
- // version for refering to the names from elsewhere. Move to stdcomp.h?
-
- // Macro for declaring all the has_facet and use_facet functions to be friends.
-
- #ifndef _RWSTD_NO_FRIEND_TEMPLATES
- #ifndef _RWSTD_NO_NAMESPACE
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- #define _RWSTD_FRIEND_USE_HAS_FACET \
- template <class Facet> friend \
- inline const Facet& std::use_facet (const locale&); \
- template <class Facet> friend \
- inline bool std::has_facet (const locale&) _RWSTD_THROW_SPEC_NULL;
- #else
- #define _RWSTD_FRIEND_USE_HAS_FACET \
- template <class Facet> friend \
- inline const Facet& std::use_facet (const locale&,Facet*); \
- template <class Facet> friend \
- inline bool std::has_facet (const locale&,Facet*) _RWSTD_THROW_SPEC_NULL;
- #endif
- #else
- #ifndef _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- #define _RWSTD_FRIEND_USE_HAS_FACET \
- template <class Facet> friend \
- inline const Facet& use_facet (const locale&); \
- template <class Facet> friend \
- inline bool has_facet (const locale&) _RWSTD_THROW_SPEC_NULL;
- #else
- #define _RWSTD_FRIEND_USE_HAS_FACET \
- template <class Facet> friend \
- inline const Facet& use_facet (const locale&,Facet*); \
- template <class Facet> friend \
- inline bool has_facet (const locale&,Facet*) _RWSTD_THROW_SPEC_NULL;
- #endif // _RWSTD_NO_TEMPLATE_ON_RETURN_TYPE
- #endif// _RWSTD_NO_NAMESPACE
- #else
- #define _RWSTD_FRIEND_USE_HAS_FACET public:
- #endif
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace __rwstd {
- using namespace std;
- #endif
-
- // Implementation class template -- timepunct<charT>
- //
- // A facet such as this should have been included in the standard. We just
- // declare it here; the definition occurs below, after locale::facet has been
- // defined.
-
- template <class charT> class timepunct;
-
- // Implementation forward declarations:
-
- class _RWSTDExport locale_imp;
- class _RWSTDExport facet_imp;
-
- class _RWSTDExport digit_map_base;
- template <class charT> class _RWSTDExportTemplate digit_map;
- template <class charT> class _RWSTDExportTemplate keyword_def;
- template <class charT> class _RWSTDExportTemplate keyword_map;
- template <class charT> class _RWSTDExportTemplate keyword_cracker;
-
- class _RWSTDExport digit_reader_base;
- template <class charT> class digit_reader_base_1;
- template <class charT,class InputIterator>
- class _RWSTDExportTemplate digit_reader;
-
- class _RWSTDExport digit_writer_base;
- template <class charT>
- class _RWSTDExportTemplate digit_writer_base_1;
- template <class charT,class OutputIterator>
- class _RWSTDExportTemplate digit_writer;
-
- // ------------------------------------
- // Implementation class -- ref_counted.
- // ------------------------------------
-
- // Common base class for reference-counted classes. Currently used only by
- // locale_imp and facet_imp, but could be used more generally.
-
- class _RWSTDExport ref_counted {
- friend class _STD::locale;
-
- size_t ref_count_;
- #ifdef _RWSTD_MULTI_THREAD
- _RWSTDMutex mutex_;
- #endif
-
- protected:
- ref_counted (size_t initial_refs):
- ref_count_(initial_refs) { }
-
- // Ensure derived class destructors are always virtual.
- virtual ~ref_counted (void);
-
- // Does protected access make these accessible to friends of derived classes?
- // We're about to find out ...
-
- static void add_reference (ref_counted *ob) {
- STDGUARD(ob->mutex_);
- ++ob->ref_count_;
- }
-
- static void remove_reference (ref_counted *ob) {
- size_t refs;
- {
- STDGUARD(ob->mutex_);
- refs=--ob->ref_count_;
- }
- if (!refs)
- delete ob;
- }
-
- static void add_possible_reference (ref_counted *ob) {
- if (ob)
- add_reference(ob);
- }
-
- static void remove_possible_reference (ref_counted *ob) {
- if (ob)
- remove_reference(ob);
- }
- };
-
- // We would prefer to define locale::id and locale::facet entirely as nested
- // classes of locale, but current compilers have problems with out-of-line
- // definition of members of such classes, so we have to derive most of their
- // behavior from unnested implementation classes:
-
- // --------------------------------------
- // Implementation class -- locale_id_imp.
- // --------------------------------------
-
- class _RWSTDExport locale_id_imp {
- protected:
- _MUTABLE size_t id_;
- static size_t last_used_id_;
- void init() const;
- public:
- locale_id_imp () : id_ (0) {} // __BORLANDC__
-
- };
-
- // ----------------------------------
- // Implementation class -- facet_imp.
- // ----------------------------------
-
- class _RWSTDExport facet_imp: public ref_counted
- {
- _RWSTD_FRIEND_USE_HAS_FACET
- friend class locale_imp;
- friend class _STD::locale;
-
- enum {
- facet_cat_ = 0,
- ok_implicit_ = 0,
- init_done = 0x0001
- };
-
- private:
- int flags_;
- int category_; // Should be same type as locale::category
-
- protected:
- facet_imp (size_t refs, int cat=0):
- ref_counted(refs), flags_(0), category_(cat) { }
-
- // rw_init() is called by locale::install the first time a facet is installed
- // in its first locale. Some facets override it to set up private data that
- // depends on return values of virtual do_xxx functions that can't be called
- // in the constructor.
- virtual void rw_init (void) { }
- };
-
-
- #ifndef _RWSTD_NO_NAMESPACE
- }
- #endif
-
- #include "rw/locvecto.h"
-
- #ifndef _RWSTD_NO_NAMESPACE
- namespace __rwstd {
- #endif
-
- // -----------------------------------
- // Implementation class -- locale_imp.
- // -----------------------------------
-
- class _RWSTDExport locale_imp: public ref_counted
- {
- _RWSTD_FRIEND_USE_HAS_FACET
- friend class _STD::locale;
-
- // Same type as locale::category ...
- typedef int locale_category;
- locale_vector<string> names_;
- locale_vector<facet_imp*> vec_;
-
- locale_category native_cats_;
- locale_category named_cats_;
- string big_name_;
- bool named_;
-
- locale_imp (size_t sz=36, size_t refs=0);
- locale_imp (const locale_imp&,size_t refs);
- ~locale_imp ();
-
- #ifdef _MSC_VER
- public:
- #endif
- inline facet_imp *get_facet (size_t i) const
- { return i<vec_.size()? vec_[i] : NULL; }
- #ifdef _MSC_VER
- private:
- #endif
-
- const char *category_name (locale_category) const;
-
- // Map C library LC_xxx constants into facet categories.
- static locale_category map_category (locale_category);
-
- // Parse a locale name into category names.
- static bool parse_name (locale_vector<string>&,const char*);
- // Combine category names to create a locale name.
- static bool build_name (string&,const locale_vector<string>&);
- };
-
- // ---------------------------------------
- // Implementation class -- digit_map_base.
- // ---------------------------------------
-
- // A place to stash some static constants, so that each instantiation of the
- // derived class rwstd::digit_map does not have to have a separate copy.
-
- struct _RWSTDExport digit_map_base {
- enum { zero, minus, plus, X, x, E, e };
- static const char punct_chars[7]; // "0-+XxEe"
- static const char digit_chars[22]; // "0123456789ABCDEFabcdef"
- static const char char_values[22]; // Corresponding values in range 0-15
- };
-
- // --------------------------------------------------
- // Implementation class template -- digit_map<charT>.
- // --------------------------------------------------
-
- // Maps digits into their corresponding numeric values, and caches widened
- // equivalents of some number-related punctuation characters that don't depend
- // on the numpunct facet. A private instance of this class is hidden in
- // ctype<charT> for use by numeric conversion facets. A call to init must
- // precede the first call to eval if is_inited() is false. Eval returns 0-15
- // if argument is a valid digit, a negative value otherwise.
- //
- // Specialized for char for performance. The specialization assumes digits
- // fit into the char code-set in an ASCII-like manner ('0'..'9' contiguous,
- // 'A'..'F' contiguous, 'a'..'f' contiguous, '0' < 'A' < 'a').
-
- template <class charT>
- class _RWSTDExportTemplate digit_map:
- public digit_map_base
- {
- bool inited;
- charT punct_array[7];
- charT digit_array[22];
- char value_array[22];
- public:
- typedef charT char_type;
-
- digit_map (void): inited(false) { }
- bool is_inited (void) const { return inited; }
- void init (const ctype<charT>& ct);
- const charT *get_punct (void) const { return punct_array; }
- int eval (charT) const;
-
- // Can-opener for getting the digit_map out of a ctype. (Works because of
- // the friend declaration in ctype_helper<charT> below.)
- static inline const digit_map<charT>&
- get_digit_map (const ctype<charT>&);
- };
-
- _RWSTD_TEMPLATE
- class _RWSTDExportTemplate digit_map<char>:
- public digit_map_base
- {
- public:
- typedef char char_type;
-
- bool is_inited (void) const { return true; }
- const char *get_punct (void) const { return punct_chars; }
- inline int eval (char c) const;
- static inline const digit_map<char>&
- get_digit_map (const ctype<char>&);
-
- private:
- // These declarations stop BC5 from firing the template for member function
- // digit_map<charT>::init on char, then complaining that init and inited are
- // not members of digit_map<char>.
- void init (const ctype<char>&);
- bool inited;
- };
-
- // ----------------------------------------------------
- // Implementation class template -- keyword_def<charT>.
- // ----------------------------------------------------
-
- // Helper class used in parsing keywords from input (such as true/false in
- // num_get, month and day names in time_get, etc).
-
- template <class charT>
- class _RWSTDExportTemplate keyword_def {
- public:
- const charT *s;
- int v;
- };
-
- // ----------------------------------------------------
- // Implementation class template -- keyword_map<charT>.
- // ----------------------------------------------------
-
- // Defines a set of keywords to be recognized on input and to be written to
- // output. Private instances are hidden in numpunct (for true/false) and
- // rwstd::timepunct (for month and weekday names).
-
- template <class charT>
- class _RWSTDExportTemplate keyword_map {
- public:
- int num_defs_;
- const keyword_def<charT> *defs_;
- };
-
-
-
- // ---------------------------------------------------
- // Implementation class template -- punct_data<charT>.
- // ---------------------------------------------------
-
- // Common base class for rwstd::numpunct_data and rwstd::moneypunct_data.
-
- template <class charT>
- class _RWSTDExportTemplate punct_data {
- friend class digit_reader_base_1<charT>;
- friend class digit_writer_base_1<charT>;
- public:
- typedef basic_string<charT,char_traits<charT>,allocator<charT> > string_type;
- protected:
- charT dp_, ts_;
- string gr_;
- };
-
-
- // ------------------------------------------------------
- // Implementation function templates -- create_xxx_facet.
- // ------------------------------------------------------
-
- // The facet_maker<Facet>::maker_func functions described above delegate the
- // actual construction of facets to three inline function templates named
- // create_xxx_facet, where xxx is 'classic' or 'native' or 'named'. The
- // default (template) versions of these functions construct facets as follows:
- //
- // classic -- default constructor for the facet with only the refs argument.
- // native -- calls create_named_facet with a name of "".
- // named -- calls create_classic_facet, ignoring the passed name.
- //
- // This default behavior is overridden (specialized) for certain facet types.
- // In particular, create_named_facet is specialized for all facet types that
- // have a derived _byname version, to construct that version with the passed
- // name (see <rw/rwlocale>) and create_native_facet is specialized for all
- // facet types whose "native" behavior (as determined by the vendor) differs
- // from the byname facet with a name of "" (see <rw/vendor>).
-
- template <class Facet>
- inline Facet* _RWSTDExportTemplate create_named_facet
- (Facet*,const char*,size_t refs);
-
- template <class Facet>
- inline Facet* _RWSTDExportTemplate create_native_facet (Facet*);
-
- template <class Facet>
- inline Facet* _RWSTDExportTemplate create_classic_facet (Facet*)
- {
- return new Facet(1);
- }
-
-
- // ----------------------------------------------------
- // Implementation class template -- facet_maker<Facet>.
- // ----------------------------------------------------
-
- // When use_facet (inline) finds that a locale does not contain an _EXPLICIT
- // facet of the requested type, it calls locale::make__EXPLICIT (non-template)
- // to create or find the facet in a cache, and install it in the locale. As a
- // parameter to make__EXPLICIT, use_facet passes a call-back function which
- // make__EXPLICIT can call to construct a facet of the requested type if needed.
- // The call-back functions are obtained by instantiating the following helper
- // class template:
-
- template <class Facet>
- class _RWSTDExportTemplate facet_maker {
- public:
- static facet_imp *maker_func (int t, const char* name, size_t refs)
- {
- if (t==0)
- return create_classic_facet ((Facet*)0);
- else if (t==1)
- return create_native_facet ((Facet*)0);
- else
- return create_named_facet ((Facet*)0,name,refs);
- }
- };
-
- #ifndef _RWSTD_NO_NAMESPACE
- } // namespace __rwstd
- #endif
-
- #ifdef _RWSTD_COMPILE_INSTANTIATE
- #include <rw/locimpl.cc>
- #endif
-
- #pragma option pop
- #endif // __STD_RW_LOCIMPL__
-